
#include <iostream>
#include "recipefactory.h"

using std::unique_ptr;
using std::string;

bool XmlParser::load_file(std::string filename)
{
	xml_doc = unique_ptr<TiXmlDocument>(new TiXmlDocument( filename.c_str() )); 
	
	if(xml_doc.get() == NULL)
	{
		std::cout << "creation of document object failed" << std::endl;
		return false;
	}
	
	if(!xml_doc->LoadFile())
	{
		std::cout << "load failed" << std::endl;		
		return false;
	}
	return true;
}


unique_ptr<Recipe> RecipeFactory::get_recipe(string drink_key, string filename)
{
	unique_ptr<Recipe> null_recipe;
	TiXmlDocument doc( filename.c_str() ); 
	if(!doc.LoadFile())
	{
		std::cout << "load failed" << std::endl;		
		return null_recipe;
	}

	TiXmlNode* recipes_node = doc.FirstChild("Recipes");
	
	if(recipes_node == NULL)
	{
		std::cout << "could not find recipe list!" << std::endl;
		return null_recipe;
	}
	
	TiXmlNode* drink_node = find_drink(drink_key, recipes_node);
	
	if(drink_node == NULL)
	{
		std::cout << "could not find drink!" << std::endl;
		return null_recipe;
	}
	
	
	auto recipe = build_recipe(drink_node, drink_key);
	
	return recipe;
}


TiXmlNode* RecipeFactory::find_drink(string drink_key, TiXmlNode* recipes_node)
{
	TiXmlNode* pDrink = NULL;
	
	for ( pDrink = recipes_node->FirstChildElement("Drink"); pDrink != 0; pDrink = pDrink->NextSiblingElement("Drink")) 
	{
		if (get_child_text("Key", pDrink).compare(drink_key) == 0)
		{
			break;
		}
	}

	return pDrink;
}


string RecipeFactory::get_element_text(TiXmlNode* parent)
{
	string text = "";
	
	TiXmlNode* pChild = NULL;
	for ( pChild = parent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) 
	{
		if (pChild->Type() == TiXmlNode::TINYXML_TEXT)
		{
			text = pChild->Value();
			break;
		}
	}
	return text;
}


string RecipeFactory::get_child_text(string name, TiXmlNode* parent)
{
	auto name_element = parent->FirstChildElement(name);
	if (name_element == NULL) {	return string(""); }
	
	return get_element_text(name_element);
}



unique_ptr<Recipe> RecipeFactory::build_recipe(TiXmlNode* drink_node, string drink_key)
{
	unique_ptr<Recipe> null_recipe;
	
	string drink_name = get_child_text("Name", drink_node);
	if(drink_name.length() == 0){ return null_recipe; }
	
	auto ingredients_element = drink_node->FirstChildElement("Ingredients");
	if (ingredients_element == NULL) {	return null_recipe; }
	
	auto recipe = unique_ptr<Recipe>(new Recipe(drink_key, drink_name));
	
	TiXmlNode* ingredient = NULL;
	for ( ingredient = ingredients_element->FirstChild(); ingredient != 0; ingredient = ingredient->NextSibling()) 
	{
		string ingredient_key = get_child_text("Key", ingredient);
		if(ingredient_key.length() == 0){ return null_recipe; }
		
		string ingredient_name = get_child_text("Name", ingredient);
		if(ingredient_name.length() == 0){ return null_recipe; }
		
		string ingredient_amount = get_child_text("Amount", ingredient);
		if(ingredient_amount.length() == 0){ return null_recipe; }
		
		recipe->add_ingredient(ingredient_key, ingredient_name, atof(ingredient_amount.c_str()));	
	}

	return recipe;
}

